package com.ruoyi.system.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.system.commons.utils.ChatchatGLM3;
import com.ruoyi.system.commons.utils.Constants;
import com.ruoyi.system.domain.PromptModel;
import com.ruoyi.system.domain.Tool;
import com.ruoyi.system.domain.ToolKit;
import com.ruoyi.system.domain.dto.ResponseInterpretationDto;
import com.ruoyi.system.domain.dto.ToolJsonDto;
import com.ruoyi.system.domain.dto.ToolJsonResponseDto;
import com.ruoyi.system.mapper.PromptMapper;
import com.ruoyi.system.service.PromptService;
import com.ruoyi.system.service.ToolKitService;
import com.ruoyi.system.service.ToolService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.text.StringSubstitutor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

/**
 * @author ：Wangziyi
 * @date ：Created in 2023/12/17 17:24
 * @description：ToDo
 * @modified By：
 * @version: 1.0
 */


@Service
@Slf4j
public class PromptServiceImpl extends ServiceImpl<PromptMapper, PromptModel> implements PromptService {

    @Autowired
    ToolKitService toolKitService;

    @Autowired
    ToolService toolService;

    @Override
    public PromptModel queryPromptByTName(String tName) {
        LambdaQueryWrapper<PromptModel> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PromptModel::getTName,tName);
        queryWrapper.eq(PromptModel::getIsDeleted,0);
        List<PromptModel> list = this.list(queryWrapper);
        PromptModel res = null;
        if (list.size() > 0){
            res = list.get(0);
        }else {
            throw new ServiceException("prompt不存在！");
        }
        return res;
    }

    @Override
    public String getPromptByToolName(String toolName) {

        return null;
    }

    /**
     * 组装工具大的prompt
     * @param tool
     * @return
     */
    @Override
    public String assemblePrompt(ToolJsonDto tool) {
        String promptTemplate = Constants.TOOL_PROMPT_TEMPLATE;
        Map valuesMap = new HashMap<>();
        valuesMap.put("toolSetRole",tool.getToolSetRole());
        valuesMap.put("toolName", tool.getToolName());
        valuesMap.put("toolDesc",tool.getDescription());
        List<ToolJsonDto.Required> paramPairs = new ArrayList<>();
        // 根据请求类型，GET从params中获取，POST从body中获取所需参数
        String requestType = tool.getRequestType();
        if (requestType.equals("GET")) {
            paramPairs = tool.getParams().getRequired();
        }else if(requestType.equals("POST")){
            paramPairs = tool.getBody().getRequired();
        }

        String paramModel = Constants.PARAM_TEMPLATE;

        String paramModels = "";
        for(ToolJsonDto.Required paramPair : paramPairs){
            String paramName = paramPair.getDescription();
            Map valuesMap2 = new HashMap<>();
            valuesMap2.put("paramName",paramName);
            StringSubstitutor sub2 = new StringSubstitutor(valuesMap2);
            paramModels += sub2.replace(paramModel);
        }
        valuesMap.put("paramModels", paramModels);
        StringSubstitutor sub = new StringSubstitutor(valuesMap);
        String resolvedString = sub.replace(promptTemplate);
        System.out.println(resolvedString);
        return resolvedString;
    }

    /**
     * 组装查询工具链的prompt
     * @param tkName
     * @return
     */
    @Override
    public String assembleIRPrompt(String tkName) {
        String promptTemplate =Constants.TOOL_STEP_PROMPT_TEMPLATE;
        ToolKit tk = toolKitService.getToolkitByName(tkName);
        Map valuesMap = new HashMap<>();
        valuesMap.put("toolKitRole",tk.getTkRole());
        List<Tool> tools = toolService.getToolByToolkitName(tkName);
        String num = "";
        if(tools.size() == 0)
            log.error("工具集中没有工具！");
        else
            num = String.valueOf(tools.size());
        String toolDesc = "";
        String toolDescTemplate = Constants.TOOL_DESC_MODEL;
        String toolList = "";
        String toolListTemplate = Constants.TOOL_LIST_TEMPLATE;
        for(Tool tool : tools){
            Map valuesMap2 = new HashMap<>();
            valuesMap2.put("toolName",tool.getResourceName());
            StringSubstitutor subList = new StringSubstitutor(valuesMap2);
            toolList += subList.replace(toolListTemplate);
            valuesMap2.put("toolDescription",tool.getDescription());
            StringSubstitutor sub2 = new StringSubstitutor(valuesMap2);
            toolDesc += sub2.replace(toolDescTemplate);
        }
        toolDesc = toolDesc.substring(0,toolDesc.length() - 1);
        toolList = toolList.substring(0,toolList.length() - 1);
        valuesMap.put("toolNum",num);
        valuesMap.put("toolNameList",toolList);
        valuesMap.put("nameDescriptions",toolDesc);
        StringSubstitutor sub = new StringSubstitutor(valuesMap);
        String ans = sub.replace(promptTemplate);
        log.info("拼接结果：" + ans);
        return ans;
    }

    /**
     * 组装意图识别prompt
     * @return
     */
    @Override
    public String assembleFirstPrompt() {
        String promptTemplate =Constants.INTENTION_RECOGNITION_SYS_PROMPT;
        List<ToolKit> toolKits = toolKitService.getAllTookit();
        String num = String.valueOf(toolKits.size());
        String intentionNamesList = "";
        String intentionPair = "";
        for(ToolKit toolKit : toolKits){
            String tkNameTemplate = Constants.TK_NAME_TEMPLATE;
            String descPair = Constants.DESC_PAIR_TEMPLATE;
            String intention = toolKit.getTkIntention();
            String name = toolKit.getTkName();
            Map valuesMap = new HashMap<>();
            valuesMap.put("intention",intention);
            valuesMap.put("name",name);
            StringSubstitutor sub2 = new StringSubstitutor(valuesMap);
            intentionNamesList += sub2.replace(tkNameTemplate);
            StringSubstitutor sub = new StringSubstitutor(valuesMap);
            intentionPair += sub.replace(descPair);
        }
        intentionNamesList = intentionNamesList.substring(0,intentionNamesList.length() - 1);
        intentionPair = intentionPair.substring(0,intentionPair.length() - 1);
        Map valuesMap = new HashMap<>();
        valuesMap.put("toolkitNum",num);
        valuesMap.put("intentionNamesList",intentionNamesList);
        valuesMap.put("intentionPair",intentionPair);
        StringSubstitutor sub = new StringSubstitutor(valuesMap);
        String ans = sub.replace(promptTemplate);
        log.info("拼接结果：" + ans);
        return ans;
    }

    public String assembleRIPrompt(String toolKitName,String question,String toolName,String response) {
        // 根据工具名称从数据库中获取对应的json文件
        ToolJsonResponseDto tool = toolService.getToolJsonByToolName(toolName);
        String template = Constants.RESULT_INTERPRETATION_PROMPT_TEMPLATE;
        Map<String, String> map = new HashMap<>();
        List<ToolJsonResponseDto.ResponseContent.Required> requiredList = tool.getResponseContent().getRequired();
        StringBuilder resExplain = new StringBuilder();
        for(ToolJsonResponseDto.ResponseContent.Required requiredParam : requiredList){
            resExplain.append("- \"").append(requiredParam.getResultName()).append("\"->\"").append(requiredParam.getDescription()).append("\"\n");
        }
        if (resExplain.length() > 0) {
            resExplain.deleteCharAt(resExplain.length() - 1);
        }
        map.put("toolKitName", toolKitName);
        map.put("toolUsed", tool.getToolName());
        map.put("lastResult", response);
        map.put("resExplain", resExplain.toString());
        map.put("userQuestion", question);
        StringSubstitutor sub = new StringSubstitutor(map);
        ChatchatGLM3 chatchatGLM3 = new ChatchatGLM3();
        String ans = chatchatGLM3.getGLM3Response(sub.replace(template));
        log.info("原始问题：\n" + sub.replace(template));
//        log.info("拼装结果：\n",ans);
        return ans;
    }

    @Override
    public String assembleResultPrompt(String toolName, String intention, String result) {
        String promptTemplate = Constants.RESULT_CONCLUSION;
        // 根据工具名称从数据库中获取对应的json文件
        ToolJsonResponseDto tool = toolService.getToolJsonByToolName(toolName);
//        String template = Constants.RESULT_INTERPRETATION_PROMPT_TEMPLATE;
        Map<String, String> map = new HashMap<>();
        List<ToolJsonResponseDto.ResponseContent.Required> requiredList = tool.getResponseContent().getRequired();
        StringBuilder resExplain = new StringBuilder();
        for(ToolJsonResponseDto.ResponseContent.Required requiredParam : requiredList){
            resExplain.append("- \"").append(requiredParam.getResultName()).append("\"->\"").append(requiredParam.getDescription()).append("\"\n");
        }
        if (resExplain.length() > 0) {
            resExplain.deleteCharAt(resExplain.length() - 1);
        }
        Map valuesMap = new HashMap<>();
        valuesMap.put("toolName",toolName);
        valuesMap.put("intention",intention);
        valuesMap.put("result",result);
        valuesMap.put("resExplain",resExplain.toString());
        StringSubstitutor sub = new StringSubstitutor(valuesMap);
        String ans = sub.replace(promptTemplate);
        ChatchatGLM3 chatchatGLM3 = new ChatchatGLM3();
        String fans = " 为了解决这个问题，上一步调用了" + toolName + ",得到的结果是 ";
        log.info("对基座大模型提问："+ans);
        fans += chatchatGLM3.getGLM3Response(ans);
        fans += " 请根据这一条件回答初始的问题：";
        log.info("合成结果：\n" + fans);
        return fans;
    }

}
